package com.z.redis.command.impl.zset;

import com.z.redis.RedisCore;
import com.z.redis.command.Command;
import com.z.redis.command.CommandType;
import com.z.redis.datatype.BytesWrapper;
import com.z.redis.datatype.RedisData;
import com.z.redis.datatype.RedisZset;
import com.z.redis.resp.BulkString;
import com.z.redis.resp.Resp;
import com.z.redis.resp.RespArray;
import io.netty.channel.ChannelHandlerContext;

import java.util.List;
import java.util.stream.Stream;

/**
 * zrange key start end
 * 通过索引区间返回有序集合成指定区间内的成员
 */
public class Zrange implements Command {
    private BytesWrapper key;
    private int start;
    private int end;

    @Override
    public CommandType type(){
        return CommandType.zrevrange;
    }

    @Override
    public void setContent(Resp[] array){
        key = ((BulkString) array[1]).getContent();
        start = Integer.parseInt(((BulkString) array[2]).getContent().toUTF8String());
        end = Integer.parseInt(((BulkString) array[3]).getContent().toUTF8String());
    }

    @Override
    public void handle(ChannelHandlerContext ctx, RedisCore redisCore){
        RedisData redisData = redisCore.get(key);
        if(redisData == null){
            ctx.writeAndFlush(BulkString.NullBulkString);
        }else if(redisData instanceof RedisZset){
            List<RedisZset.ZsetKey> members = ((RedisZset) redisData).range(start, end);
            Resp[] resps = members.stream().flatMap(key -> {
                Resp[] info = new Resp[2];
                info[0] = new BulkString(key.getKey());
                info[1] = new BulkString(new BytesWrapper(String.valueOf(key.getScore()).getBytes(CHARSET)));
                return Stream.of(info);
            }).toArray(Resp[]::new);
            ctx.writeAndFlush(new RespArray(resps));
        }else{
            throw new UnsupportedOperationException("type not Zset");
        }
    }
}
